
package vivace.view;

import javax.swing.*;
import vivace.model.Project;
import java.awt.*;
import java.util.Observable;
import java.util.Observer;

/**
 * This is the timline Panel in the TrackContent
 **/
public class Timeline extends JPanel implements Observer {

	private static final int MIN_TICKS = 16000;
	
	private Project model;

	//Set up the variables
	int		currEvent;
	int		countNumber;
	int		lengthQuartInPixel;
	int		pixelBig;
	
	double	pixelSmall;
	double	pixelSmallSpace;
	double	ticksPerCurrQuarter;
	double	ticksCounter;
	double 	ticksPerQuarter;
	
	int[][] timeSignature;

	/**
	 * Constructor
	 **/
	public Timeline(Project model) {
		this.model = model;
		this.model.addObserver(this);

		//The nice blue color of the timeline in RGB
		this.setBackground(Color.decode("#273c4f"));
		
	}

	/**
	 * paintComponent - everything to be drawn in the timeline is conctructed here
	 */
	public void paintComponent(Graphics g){
		super.paintComponent(g);

		//Specify the font properties
		g.setFont(new Font("Default", Font.BOLD, 10));

		//White is the color of the text and the fat lines
		g.setColor(Color.white);

		//Get a 2D list with information about the time signatures
		timeSignature = model.getTimeSignatures();

		//Number of ticks of a 4/4
		ticksPerQuarter = model.getPPQ() * 4;

		//How long is a 4/4 in pixels
		lengthQuartInPixel = model.getZoomLevel();
		
		//This counter keep track of the number of ticks into the midi-file we are
		ticksCounter = 0;

		//Keeps track of what event (timesignature) we are calculating on
		currEvent = 0;

		//The pixels where the big line will be painted
		pixelBig = 0;

		//The pixels where the small line will be painted
		pixelSmall = 0;

		//The difference in pixel between small lines in current time signature
		pixelSmallSpace = 0;

		//what time signature are we at
		countNumber = 0;

		//Paint as long as the song contains information
		while(ticksCounter <= model.getSequenceLength() || ticksCounter <= MIN_TICKS){

			//The fat line at the start of each time signature
			g.fillRect(pixelBig, 0, 1, 7);

			//Draw the numbers
			g.drawString("" + countNumber, pixelBig + 1, 17);

			//The small lines are pianted after a big one, so set the small lines to begin at the current big line x-marker
			pixelSmall = pixelBig;

			//Calculate where next BIG marker will be;
			pixelBig = pixelBig + (lengthQuartInPixel*timeSignature[currEvent][0])/timeSignature[currEvent][1];

			//Paint the small lines between the big ones
			for(int z = 0; z < (timeSignature[currEvent][0]-1); z++) {

				//Calculate where the small lines will be put
				//If this is the first line after a BIG line
				if(z == 0){

					//Then set up the space between each small line in a time signature
					pixelSmallSpace = (pixelBig-pixelSmall)/timeSignature[currEvent][0];

					//Then make the first tick draw one space after the 
					pixelSmall = pixelSmall + pixelSmallSpace;
					
				} else {

					//Otherwise step a small space more
					pixelSmall = pixelSmall + pixelSmallSpace;
				}

				//Draw the small line at the ticksSmall pixel value
				g.drawLine((int)pixelSmall, 0, (int)pixelSmall, 4);

			}

			//If the next timeSignature is the current tickCounter and the upcoming timeSignature is not the first one ...
			if(timeSignature[currEvent+1][2] == ticksCounter && (timeSignature[currEvent+1][2] != 0)){

				//Increase the value of the currentEvent, this will make the program draw a new time signature
				currEvent++;

				//If this is the first timeSignature in the midi-file ...
				if(countNumber == 0 ){

					//We will have to get the information from the current event not the new
					//Set the number of ticks between the current time signature
					ticksPerCurrQuarter = (ticksPerQuarter*timeSignature[currEvent-1][0])/timeSignature[currEvent-1][1];

				} else {

					//else we set the number of ticks between the current time signature to the upcoming time signature
					ticksPerCurrQuarter = (ticksPerQuarter*timeSignature[currEvent][0])/timeSignature[currEvent][1];
				}

			//If the track only contains one timesignature we dont want to update to a new one
			} else {

				ticksPerCurrQuarter = (ticksPerQuarter*timeSignature[currEvent][0])/timeSignature[currEvent][1];
			}

			//The ticksCounter is the old ticks + the new number of ticks between the current time signature
			ticksCounter = ticksCounter + ticksPerCurrQuarter;

			//Increase timesignature counter
			countNumber++;
		}

		//Paint the final big line and text
		g.fillRect(pixelBig, 0, 1, 7);

		g.drawString("" + countNumber, pixelBig + 1, 17);

	}


	public void update(Observable o,Object arg) { 

		repaint();
	}

}
